﻿using System;
using System.Collections.Generic;
using System.Text;

//define server information list type
using ServerInfoList = System.Collections.Generic.List<ServerInfoCache.CacheUnit>;

//server information cache
public class ServerInfoCache
{
    #region private struct
    //cache unit
    public struct CacheUnit
    {
        public global.eServerType ServerType;
        public int                Port;
        public int                WorldGroup;
        public string             IpAddr;
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="server_type"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="group"></param>
        public CacheUnit(global.eServerType server_type, string ip, int port, int group)
        {
            ServerType = server_type;
            Port = port;
            WorldGroup = group;
            IpAddr = ip;
        }
    }
    #endregion
    #region private variable
    //lock object
    private Object m_lockObj = new Object();
    //server list
    private ServerInfoList[] m_listServer;
    #endregion

    #region constructor
    /// <summary>
    /// constructor
    /// </summary>
    public ServerInfoCache()
    {
        int MAX_SERVER_TYPE = Enum.GetValues(typeof(global.eServerType)).Length;
        m_listServer = new ServerInfoList[MAX_SERVER_TYPE];
        for (int i = 0; i < MAX_SERVER_TYPE; ++i)
        {
            m_listServer[i] = new ServerInfoList();
        }
    }

    #endregion

    #region external call
    /// <summary>
    /// check this server whether exists
    /// </summary>
    /// <param name="serverType"></param>
    /// <param name="ip"></param>
    /// <param name="port"></param>
    /// <returns></returns>
    private bool IsExists(global.eServerType serverType, string ip, int port)
    {
        ServerInfoList list = m_listServer[(int)serverType];
        foreach (CacheUnit info in list)
        {
            if (info.ServerType.Equals(serverType) && info.IpAddr.Equals(ip) && info.Port.Equals(port))
                return true;
        }

        return false;
    }

    /// <summary>
    /// add a server information into the list
    /// </summary>
    /// <param name="unit"></param>
    /// <returns></returns>
    public bool AddServerInfo(gatewayserver.ServerInfo info)
    {
        lock (m_lockObj)
        {
            if (IsExists(info.ServerType, info.IpAddr, info.Port) == false)
            {
                CacheUnit unit = new CacheUnit(info.ServerType, info.IpAddr, info.Port, info.WorldGroup);
                m_listServer[(int)info.ServerType].Add(unit);
                return true;
            }
        }

        return false;
    }

    /// <summary>
    /// remove a server information from the list
    /// </summary>
    /// <param name="unit"></param>
    /// <returns></returns>
    public bool RemoveServerInfo(CacheUnit unit)
    {
        lock (m_lockObj)
        {
            return m_listServer[(int)unit.ServerType].Remove(unit);
        }
    }

    /// <summary>
    /// get server list
    /// </summary>
    /// <param name="server_type"></param>
    /// <returns></returns>
    public ServerInfoList GetServeInfoList(global.eServerType server_type)
    {
        lock (m_lockObj)
        {
            ServerInfoList list = new List<CacheUnit>();
            list.AddRange(m_listServer[(int)server_type]);
            return list;
        }
    }
    #endregion
}